package main

import "fmt"

/*
注 1：指针也是有零值的，它的零值是 nil。如果只是声明一个指针，var p *<type>，那么这个指针就是 nil，是不能通过这个指针获取数据的，必须对这个指针赋值之后，才可以访问指针指向的值。

注 2：指针不能直接计算，不能像 C/C++ 中一样，直接对指针作加减操作，达到偏移访问的目的。在 Go 中，如果对指针做计算操作，会直接报错，无法完成编译。
*/

var p1 *int
var p2 *string

func main() {
	i := 1
	s := "Hello"
	// 基础类型数据，必须使用变量名获取指针，无法直接通过字面量获取指针
	// 因为字面量会在编译期被声明为成常量，不能获取到内存中的指针信息
	p1 = &i
	p2 = &s

	//获取指针的指针
	p3 := &p2
	fmt.Println(p1)
	fmt.Println(p2)
	fmt.Println(p3)

	/*
		| 符号 | 作用 | 示例 | 说明 |
		|------|--------------|--------------|------------------------|
		| & | 取地址 | p := &a | 获取变量 a 的地址 |
		| * | 解引用/取值 | v := *p | 获取指针 p 指向的值 |
	*/
	var p1 *int //定义一个指针
	j := 1
	p1 = &j               //指针p1指向j的地址
	fmt.Println(*p1 == j) //解p1的地址，拿到p1地址的值
	*p1 = 2
	fmt.Println(j)

	a := 10
	p := &a
	fmt.Println(*p)
	*p = 20
	fmt.Println(a)

	//指针不能直接参与计算，否则会在编译的时候就包错
	/*	var c int
		var p2 *int
		p2 = &c
		p2 = p2 + 1
		fmt.Println(p2)*/
}
